home *** CD-ROM | disk | FTP | other *** search
-
- /*
- File: TransformLibrary.c
-
- Contains: graphics libraries - operations on transforms
-
- Written by: Cary Clark, Georgiann Delaney, Michael Fairman, Dave Good, Robert Johnson, Keith McGreggor, Oliver Steele, David Van Brink, Chris Yerga
-
- Copyright: © 1995 by Apple Computer, Inc., all rights reserved.
-
- Change History (most recent first):
-
- <2> 1/9/95 JD changed 'boolean' to 'Boolean'
- <1> 1/9/95 JD First checked in.
- */
-
- #include <Memory.h>
- #include "GraphicsLibraries.h"
-
- gxViewPort GetTransformViewPort(gxTransform xform)
- {
- short portCount;
-
- if (xform == nil)
- xform = GXGetShapeTransform(GXGetDefaultShape(gxEmptyType));
- portCount = GXGetTransformViewPorts(xform, nil);
- if (portCount == 0)
- return nil;
- else if (portCount <= 10) { /* use the stack if there's a reasonable number of ports */
- gxViewPort ports[10];
-
- GXGetTransformViewPorts(xform, ports);
- return ports[0];
- } else { /* else get memory from the heap */
- gxViewPort *ports;
- gxViewPort port;
-
- ports = (gxViewPort *) NewPtr(portCount * sizeof(gxViewPort));
- GXGetTransformViewPorts(xform, ports);
- port = ports[0];
- DisposePtr((Ptr) ports);
- return port;
- }
- }
-
- void SetTransformViewPort(gxTransform xForm, gxViewPort port)
- {
- GXSetTransformViewPorts(xForm, 1, &port);
- }
-
-
- void AddToTransformViewPort(gxTransform xform, gxViewPort newPort)
- {
- gxViewPort *ports, *portPtr;
- short portCount, count;
-
- if (xform == nil)
- xform = GXGetShapeTransform(GXGetDefaultShape(gxEmptyType));
- count = portCount = GXGetTransformViewPorts(xform, nil) + 1;
- portPtr = ports = (gxViewPort *) NewPtr(portCount * sizeof(gxViewPort));
- GXGetTransformViewPorts(xform, ports);
- while (--count > 0) /* do nothing if port order is already in transform */
- if (*portPtr++ == newPort)
- goto disposeTemp;
- *portPtr = newPort;
- GXSetTransformViewPorts(xform, portCount, ports);
- disposeTemp:
- DisposePtr((Ptr) ports);
- }
-
- void SetShapeViewPort(gxShape sh, gxViewPort port)
- {
- GXSetShapeViewPorts(sh, 1, &port);
- }
-
- gxViewPort GetShapeViewPort(gxShape sh)
- {
- return GetTransformViewPort(GXGetShapeTransform(sh));
- }
-
- void SetDeepShapeViewPorts(gxShape sh, long portCount, const gxViewPort portList[])
- {
- if (GXGetShapeType(sh) == gxPictureType) {
- register short count = GXGetPicture(sh, nil, nil, nil, nil);
- gxShape itemShape;
- gxTransform itemTransform;
-
- while( count ) {
- GXGetPictureParts(sh, count, 1, &itemShape, nil, nil, &itemTransform);
- if (itemTransform)
- GXSetTransformViewPorts(itemTransform, portCount, portList);
- SetDeepShapeViewPorts(itemShape, portCount, portList);
- --count;
- }
- }
- GXSetShapeViewPorts(sh, portCount, portList);
- }
-
-
- void SetDeepShapeTransform(gxShape sh, gxTransform xform)
- {
- if (GXGetShapeType(sh) == gxPictureType) {
- register short count = GXGetPicture(sh, nil, nil, nil, nil);
- gxShape itemShape;
- gxTransform itemTransform;
-
- while (count) {
- GXGetPictureParts(sh, count, 1, &itemShape, nil, nil, &itemTransform);
- if (itemTransform) {
- gxStyle itemStyle;
- gxInk itemInk;
-
- GXGetPictureParts(sh, count, 1, &itemShape, &itemStyle, &itemInk, &itemTransform);
- GXSetPictureParts(sh, count, 1, 1, &itemShape, &itemStyle, &itemInk, &itemTransform);
- }
- SetDeepShapeTransform(itemShape, xform);
- count--;
- }
- }
- GXSetShapeTransform(sh, xform);
- }
-
- void SetDeepShapeViewPort(gxShape sh, gxViewPort newPort)
- {
- SetDeepShapeViewPorts(sh, 1, &newPort);
- }
-
- void PreMapTransform(gxTransform source, gxMapping *map)
- {
- gxMapping copy, xform;
-
- CopyToMapping(©, map);
- GXGetTransformMapping(source, &xform);
- MapMapping(©, &xform);
- GXSetTransformMapping(source, ©);
- }
-
- #ifdef debugging
- static void ClearBytes(char *block, long length)
- {
- while (--length >= 0)
- *block++ = 0;
- }
- #endif
-
- /* Set each of the default shapes' transforms to have only the gxViewPort in their gxViewPort list.
- Default shapes that shared a gxTransform with each other will still share it; those with unique
- gxTransform will still have unique ones. Default shapes that shared a gxTransform with a non-
- default gxShape will do so no longer: only the default shapes have their gxTransform changed. */
- void SetDefaultViewPort(gxViewPort port)
- {
- /* xforms contains the gxTransform for each gxShape, or nil if the gxShape shares a gxTransform
- with another default gxShape. owners contains the number of default shapes that own
- the gxTransform. offset contains the index of the gxShape's gxTransform in the xforms array,
- if the gxShape share's a gxTransform with an earlier gxShape. copied is true for transforms
- that were created in this routine, and hence need to be disposed here.
-
- An index of zero means the default gxTransform. owners and offsets could be folded into the
- same array, as owners is only used where xforms is non-nil, and offsets where it is nil.
- */
- gxTransform xforms[gxPictureType + 1];
- short owners[gxPictureType + 1];
- short offsets[gxPictureType + 1];
- Boolean copied[gxPictureType + 1];
- short i, j;
-
- /* the following lines are desirable when debugging with memory flipping enabled */
- #ifdef debugging
- ClearBytes((char *) xforms, sizeof(xforms));
- ClearBytes((char *) owners, sizeof(owners));
- ClearBytes((char *) offsets, sizeof(offsets));
- ClearBytes((char *) copied, sizeof(copied));
- #endif
- /* collect the transforms into the arrays */
- for (i = gxEmptyType; i <= gxPictureType; i++) {
- xforms[i] = GXGetShapeTransform(GXGetDefaultShape(i));
- owners[i] = 1;
- copied[i] = false;
-
- for (j = gxEmptyType; j < i; j++)
- if (xforms[i] == xforms[j]) {
- xforms[i] = nil;
- offsets[i] = j;
- owners[j]++;
- break;
- }
- }
-
- /* make copies of the transforms, where necessary */
- for (i = gxEmptyType; i <= gxPictureType; i++) {
- gxTransform xform = xforms[i];
- gxViewPort oldPort;
-
- if (xform == nil) continue;
-
- /* maybe the transform already has the right port */
- if (GXGetTransformViewPorts(xform, nil) == 1 && (GXGetTransformViewPorts(xform, &oldPort), oldPort) == port)
- continue;
- if (GXGetTransformOwners(xform) != owners[i]) {
- /* some of the owners aren't default shapes */
- xforms[i] = xform = GXCopyToTransform(nil, xform);
- copied[i] = true;
- }
- GXSetTransformViewPorts(xform, 1, &port);
- }
-
- #ifdef debugging
- GXIgnoreGraphicsNotice(transform_already_set);
- #endif
- for (i = gxEmptyType; i <= gxPictureType; i++) {
- gxTransform xform = xforms[i];
-
- GXSetShapeTransform(GXGetDefaultShape(i), xform ? xform : xforms[offsets[i]]);
- if (copied[i])
- GXDisposeTransform(xform);
- }
- #ifdef debugging
- GXPopGraphicsNotice();
- #endif
- #undef defaultType
- }
-
- gxViewGroup CopyViewGroup(gxViewGroup group)
- {
- /* create a new view group */
- gxViewGroup newGroup = GXNewViewGroup();
-
- /* copy the view device list */
- { long deviceCount = GXGetViewGroupViewDevices(group, nil), count = deviceCount;
- gxViewDevice *deviceList = (gxViewDevice *) NewPtr(deviceCount * sizeof(gxViewDevice)), *list = deviceList;
- GXGetViewGroupViewDevices(group, deviceList);
- while (count--)
- { GXSetViewDeviceViewGroup(*list = GXCopyToViewDevice(nil, *list), newGroup);
- list++;
- }
- DisposePtr((Ptr) deviceList);
- }
-
- /* copy the view port list */
- { long portCount = GXGetViewGroupViewPorts(group, nil), count = portCount;
- gxViewPort *oldPortList = (gxViewPort *) NewPtr(portCount * sizeof(gxViewPort)), *oldList = oldPortList;
- gxViewPort *newPortList = (gxViewPort *) NewPtr(portCount * sizeof(gxViewPort)), *newList = newPortList;
- GXGetViewGroupViewPorts(group, oldPortList);
- while (count--)
- GXSetViewPortViewGroup(*newList++ = GXCopyToViewPort(nil, *oldList++), newGroup);
-
- /* copy the view port hierarchy */
- oldList = oldPortList; newList = newPortList;
- for (count = portCount; count--; newList++)
- { gxViewPort parent = GXGetViewPortParent(*oldList++);
- if (parent)
- { gxViewPort *optr = oldPortList, *nptr = newPortList;
- long pcnt = portCount;
- Boolean match = false;
- while (pcnt-- && !(match = *optr == parent)) { optr++; nptr++; }
- if (match) GXSetViewPortParent(*newList, *nptr);
- }
- }
- DisposePtr((Ptr) newPortList);
- DisposePtr((Ptr) oldPortList);
- }
- return newGroup;
- }
-
- /* the newGroup should have at least as many viewPorts in it as the oldGroup */
- /* ideally, newGroup and oldGroup should be copies of each other */
- gxTransform ChangeTransformViewGroup(gxTransform xform, gxViewGroup oldGroup, gxViewGroup newGroup)
- {
- long oldPortCount = GXGetViewGroupViewPorts(oldGroup, nil);
- long newPortCount = GXGetViewGroupViewPorts(newGroup, nil);
- long xformPortCount = GXGetTransformViewPorts(xform, nil);
- gxViewPort *oldPortList = (gxViewPort *) NewPtr(oldPortCount * sizeof(gxViewPort));
- gxViewPort *newPortList = (gxViewPort *) NewPtr(newPortCount * sizeof(gxViewPort));
- gxViewPort *xformPortList = (gxViewPort *) NewPtr(xformPortCount * sizeof(gxViewPort));
- GXGetViewGroupViewPorts(oldGroup, oldPortList);
- GXGetViewGroupViewPorts(newGroup, newPortList);
- GXGetTransformViewPorts(xform, xformPortList);
- { long xcnt = xformPortCount;
- gxViewPort *xptr = xformPortList;
- while (xcnt--)
- { gxViewPort order = *xptr, *optr = oldPortList, *nptr = newPortList;
- long pcnt = oldPortCount;
- Boolean match = false;
- while (pcnt-- && !(match = *optr == order)) { optr++; nptr++; }
- if (match) *xptr = *nptr;
- xptr++;
- }
- }
- GXSetTransformViewPorts(xform, xformPortCount, xformPortList);
- DisposePtr((Ptr) xformPortList);
- DisposePtr((Ptr) newPortList);
- DisposePtr((Ptr) oldPortList);
- return xform;
- }
-
- gxShape ChangeShapeViewGroup(gxShape source, gxViewGroup oldGroup, gxViewGroup newGroup)
- {
- gxTransform xform = GXGetShapeTransform(source);
- if (GXGetTransformOwners(xform) > 1) /* is it shared? */
- { xform = GXCopyToTransform(nil, xform);
- GXSetShapeTransform(source, xform);
- GXDisposeTransform(xform);
- }
- ChangeTransformViewGroup(xform, oldGroup, newGroup);
- return source;
- }
-
- gxTransform SeparateShapeTransform(gxShape source)
- {
- gxTransform old = GXCloneTransform(GXGetShapeTransform(source)), xnew = GXCopyToTransform(nil, old);
- GXSetShapeTransform(source, xnew);
- GXDisposeTransform(xnew);
- return old;
- }
-
- void ReuniteShapeTransform(gxShape target, gxTransform separate)
- {
- GXSetShapeTransform(target, separate);
- GXDisposeTransform(separate);
- return;
- }
-